package com.explment.lens.filter;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.explment.lens.entity.SysUserEntity;
import com.explment.lens.entity.securityuser.LoginUser;
import com.explment.lens.exception.BusinessException;
import com.explment.lens.service.SysUserService;
import com.explment.lens.service.redis.RedisService;
import com.explment.lens.utils.jwt.JwtTokenProvider;
import com.explment.lens.utils.result.ResultCode;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * OncePerRequestFilter 本身就是web的一个过滤器
 */

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final List<String> EXCLUDE_PATHS = Arrays.asList(
            "/api/**",
            "/api/login",
            "/api/register"
    );
    @Autowired
    private JwtTokenProvider jwtTokenProvider;
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private RedisService redisService;



    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 如果是 /api/** 路径，直接放行
        String path = request.getRequestURI();
        /*if (EXCLUDE_PATHS.stream().anyMatch(path::startsWith)) {
            filterChain.doFilter(request, response);
            return;
        }*/

        String token = extractToken(request);
        if (!StringUtils.hasText(token) || !jwtTokenProvider.validateToken(token)) {
            throw new BusinessException(ResultCode.UNAUTHORIZED, "Token is invalid or expired");
        }

        String username = jwtTokenProvider.getUsernameFromToken(token);
        if (!StringUtils.hasText(username)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "Token contains no user information");
        }

        String storedToken = (String) redisService.get("access:" + username);
        if (!StringUtils.hasText(storedToken) || !token.equals(storedToken)) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "Token does not match stored value");
        }

        SysUserEntity user = sysUserService.getOne(new QueryWrapper<SysUserEntity>().eq("account", username));
        if (null == user) {
            throw new BusinessException(ResultCode.BAD_REQUEST, "User not found");
        }
        Authentication auth = new UsernamePasswordAuthenticationToken(
                username,
                user.getPassword(),
                Collections.emptyList()
        );
        SecurityContextHolder.getContext().setAuthentication(auth);
        filterChain.doFilter(request, response);

    }

    private String extractToken(HttpServletRequest request) {
        String header = request.getHeader("Authorization");
        if (StringUtils.hasText(header) && header.startsWith("Bearer ")) {
            return header.substring(7);
        }
        return null;
    }
}
